/*
 * FaceCat图形通讯框架
 * 著作权编号:2015SR229355+2020SR0266727
 * 上海卷卷猫信息技术有限公司
 */

#include "stdafx.h"
#include "FCFile.h"

namespace FaceCat{
    bool FCFile::append(const char *file, const char *content){
        std::ofstream fs(file, std::ios::app);
        if(fs){
            fs << content;
            fs.close();
            return true;
        }
        return false;
    }
    
    bool FCFile::append(const String &file, const String &content){
        lstring sFile = FCTran::StringTostring(file);
        lstring sContent = FCTran::StringTostring(content);
        return append(sFile.c_str(), sContent.c_str());
    }
    
    void FCFile::createDirectory(const char *dir){
        mkdir(dir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
    }
    
    void FCFile::createDirectory(const String &dir){
        lstring sDir = FCTran::StringTostring(dir);
        createDirectory(sDir.c_str());
    }
    
    bool FCFile::isDirectoryExist(const char *dir)
    {
        struct stat st;
        stat(dir, &st);
        if (S_ISDIR(st.st_mode)){
            return true;
        }else{
            return false;
        }
    }
    
    bool FCFile::isFileExist(const char *file)
    {
        if(isDirectoryExist(file)){
            return false;
        }
        std::ifstream fs;
        fs.open(file, std::ios::in);
        if(fs)
        {
            fs.close();
            return true;
        }
        else
        {
            return false;
        }
    }
    
    bool FCFile::isFileExist(const String &file)
    {
        lstring sFile = FCTran::StringTostring(file);
        return isFileExist(sFile.c_str());
    }
    
    bool FCFile::isDirectoryExist(const String &dir)
    {
        lstring sDir = FCTran::StringTostring(dir);
        return isDirectoryExist(sDir.c_str());
    }
    
    bool FCFile::getDirectories(const String &dir, ArrayList<String> *dirs)
    {
        String wDir;
        ArrayList<lstring> vectors;
        lstring sDir = FCTran::StringTostring(dir);
        bool res = getDirectories(sDir.c_str(), &vectors);
        int size=(int)vectors.size();
        for (int i = 0; i < size; i++)
        {
            wDir = FCTran::stringToString(vectors.get(i));
            dirs->add(wDir);
        }
        return res;
    }
    
    long FCFile::getFileLength(const char *file){
        FILE* fp = 0;
        long fileLen = 0;
        fp = fopen(file, "rb");
        if (!fp){
            return 0;
        }
        fseek(fp, 0, SEEK_END);
        fileLen = ftell(fp);
        fclose(fp);
        return fileLen;
    }
    
    long FCFile::getFileLength(const String &file){
        lstring sFile = FCTran::StringTostring(file);
        return getFileLength(sFile.c_str());
    }

    bool FCFile::getDirectories(const char *dirName, ArrayList<lstring> *dirs)
    {
        std::vector<std::string> strs;
        DIR *dir;
        struct dirent *ptr;
        if ((dir = opendir(dirName)) == NULL){
            return false;
        }
        while ((ptr = readdir(dir)) != NULL){
            if (ptr->d_name == std::string(".") || ptr->d_name == std::string(".."))
                continue;
            else if(ptr->d_type == 8)  //file
                continue;
            else if(ptr->d_type == 10)  //link file
                continue;
            else if(ptr->d_type == 4)  //dir
                strs.push_back((std::string)dirName + "/" + ptr->d_name);
        }
        sort(strs.begin(), strs.end());
        for(int i = 0; i < strs.size(); i++){
            dirs->add(lstring(strs[i].c_str()));
        }
        closedir(dir);
        return true;
    }
    
    bool FCFile::getFiles(const char *dirName, ArrayList<lstring> *files){
        std::vector<std::string> strs;
        DIR *dir;
        struct dirent *ptr;
        if ((dir = opendir(dirName)) == NULL){
            return false;
        }
        while ((ptr = readdir(dir)) != NULL){
            if (ptr->d_name == std::string(".") || ptr->d_name == std::string(".."))
                continue;
            else if(ptr->d_type == 8)  //file
                strs.push_back((std::string)dirName + "/" + ptr->d_name);
                //files->add((lstring)dirName + "/" + ptr->d_name);
            else if(ptr->d_type == 10)  //link file
                continue;
            else if(ptr->d_type == 4)  //dir
                continue;
        }
        sort(strs.begin(), strs.end());
        for(int i = 0; i < strs.size(); i++){
            files->add(lstring(strs[i].c_str()));
        }
        closedir(dir);
        return true;
    }
    
    bool FCFile::getFiles(const String &dir, ArrayList<String> *files){
        String wFile;
        ArrayList<lstring> vectors;
        lstring sDir = FCTran::StringTostring(dir);
        bool res = getFiles(sDir.c_str(), &vectors);
        int size=(int)vectors.size();
        for (int i = 0; i < size; i++){
            wFile = FCTran::stringToString(vectors.get(i));
            files->add(wFile);
        }
        return res;
    }
    
    int FCFile::getFileState(const char *file, struct stat *buf){
        return stat(file, buf);
    }
    
    int FCFile::getFileState(const String &file, struct stat *buf){
        lstring sFile = FCTran::StringTostring(file);
        return getFileState(sFile.c_str(), buf);
    }
    
    bool FCFile::getFileName(lstring srcDirPath , ArrayList<lstring> *fileNameList)
    {
        DIR *dir;
        struct dirent *ptr;
        if ((dir=opendir(srcDirPath.c_str())) == NULL){
            return false;
        }
        while ((ptr=readdir(dir)) != NULL){
            if (ptr->d_name == lstring(".") || ptr->d_name == lstring(".."))
                continue;
            else if(ptr->d_type == 8)  //file
                fileNameList->add(ptr->d_name);
            else if(ptr->d_type == 10)  //link file
                continue;
            else if(ptr->d_type == 4)  //dir
                fileNameList->add(ptr->d_name);
        }
        closedir(dir);
        return true;
    }
    
    bool FCFile::makeDir (const lstring& pathName){
        if(::mkdir(pathName.c_str(), S_IRWXU | S_IRGRP | S_IXGRP) < 0){
            return false;
        }
        return true;
    }
    
    bool FCFile::read(const char *file, lstring *content){
        bool flag = false;
        long fileLength = getFileLength(file);
        if(fileLength > 0){
            char *str = new char[fileLength + 1];
            memset(str, '\0', fileLength + 1);
            std::ifstream fs(file, std::ios::in);
            if(fs){
                fs.read(str, fileLength);
                fs.close();
                *content = str;
                flag = true;
            }
            delete[] str;
            str = 0;
        }
        return flag;
    }
    
    bool FCFile::read(const String &file, String *content){
        lstring sFile = FCTran::StringTostring(file);
        bool flag = false;
        long fileLength = getFileLength(file);
        if(fileLength > 0){
            char *str = new char[fileLength + 1];
            memset(str, '\0', fileLength + 1);
            std::ifstream fs(sFile.c_str(), std::ios::in);
            if(fs){
                fs.read(str, fileLength);
                fs.close();
                *content = FCTran::stringToString(str);
                flag = true;
            }
            delete[] str;
            str = 0;
        }
        return flag;
    }
    
    void FCFile::removeFile(const char *file){
        remove(file);
    }
    
    void FCFile::removeFile(const String &file){
        lstring sFile = FCTran::StringTostring(file);
        return removeFile(sFile.c_str());
    }
    
    bool FCFile::write(const char *file, const char *content){
        std::ofstream fs(file, std::ios::out);
        if(fs){
            fs << content;
            fs.close();
            return true;
        }
        return false;
    }
    
    bool FCFile::write(const String &file, const String &content){
        lstring sFile = FCTran::StringTostring(file);
        lstring sContent = FCTran::StringTostring(content);
        return write(sFile.c_str(), sContent.c_str());
    }
}
